package com.sogou.ime.ui.settings.dynamic;

import java.util.ArrayList;
import java.util.HashMap;

import com.sogou.ime.ui.settings.dynamic.CandidateKeyboardLocation.CandCharacterListMode;
import com.sogou.ime.ui.settings.dynamic.SoftKeyboard.KeyBox;
import com.sogou.ime.ui.settings.dynamic.SoftKeyboard.KeyBoxRow;

public class CandidateKeyboard {
	public static int defaultCandKeyboardWidth ;
	public static int defaultCandKeyboardHeight ;
	private KeyboardCandidateCharConfig keyboardCharConfig;
	public int candKeyboardRowCnt = 0;
	public int candKeyboardColCnt = 0;
	public int candScreenColCnt = 0;
	public int keyWidth = 0;
	public int keyHeight = 0;
	public CandCharacterListMode candCharacterListMode;
	
	public CandidateKeyboard(KeyboardCandidateCharConfig keyboardCharConfig, int candKeyboardWidth, 
			int candKeyboardHeight, int keyWidth, int KeyHeight)
	{
		this.keyboardCharConfig = keyboardCharConfig;
		this.keyWidth = keyWidth;
		this.keyHeight = KeyHeight;
		candCharacterListMode = CandCharacterListMode.Character;
		calcCandKeyboardLayout(candKeyboardWidth, candKeyboardHeight, CandCharacterListMode.Character);
	}
	
	public boolean calcCandKeyboardLayout(int keyboardWidth, int keyboardHeight, CandCharacterListMode candKeyboardMode)
	{
		if (candKeyboardMode == CandCharacterListMode.Character)
		{
			candScreenColCnt = keyboardWidth / (keyWidth + CandidateKeyboardLocation.defaultColGap);
			candKeyboardRowCnt = keyboardHeight / (keyHeight + CandidateKeyboardLocation.defaultRowGap);
			ArrayList<Character> characterList = getFilteredCharacters(GlobalVar.currentKeyboard);
	//		candKeyboardColCnt = (characterList.size() + candKeyboardRowCnt -1) / candKeyboardRowCnt ;
			
			int pageCharCount = candKeyboardRowCnt * candScreenColCnt;
			candKeyboardColCnt = characterList.size() / pageCharCount * candScreenColCnt;
			if (characterList.size() % pageCharCount > candScreenColCnt)
			{
				candKeyboardColCnt += candScreenColCnt;
			}
			else
			{
				candKeyboardColCnt += characterList.size() % pageCharCount;
			}
		}
		else if (candKeyboardMode == CandCharacterListMode.Symbol)
		{
			candScreenColCnt = keyboardWidth / (keyWidth + CandidateKeyboardLocation.defaultColGap);
			candKeyboardRowCnt = keyboardHeight / (keyHeight + CandidateKeyboardLocation.defaultRowGap);
			ArrayList<Character> characterList = getFilteredSymbolCharacters(GlobalVar.currentKeyboard);
			
			int pageCharCount = candKeyboardRowCnt * candScreenColCnt;
			candKeyboardColCnt = characterList.size() / pageCharCount * candScreenColCnt;
			if (characterList.size() % pageCharCount > candScreenColCnt)
			{
				candKeyboardColCnt += candScreenColCnt;
			}
			else
			{
				candKeyboardColCnt += characterList.size() % pageCharCount;
			}
		} else {
			return false;
		}
		
		return true;
	}
	
	public int getCandKeyboardPageCount()
	{
		return (candKeyboardColCnt + candScreenColCnt - 1) / candScreenColCnt;
	}
	
	public ArrayList<Character> getFilteredCharacters(SoftKeyboard keyboard)
	{
		ArrayList<Character> filteredCharList = new ArrayList<Character>();
		HashMap<Character, Boolean> keyboardCharMap = getKeyboardCharMap(keyboard);
		
		for (Character oneChar : keyboardCharConfig.candCharList)
		{
			if (!keyboardCharMap.containsKey(oneChar))
			{
				filteredCharList.add(oneChar);
			}
		}
		
		return filteredCharList;
	}

	private  HashMap<Character, Boolean> getKeyboardCharMap(SoftKeyboard keyboard) {
		HashMap<Character, Boolean> keyboardCharMap = new HashMap<Character, Boolean>();
		
		for (int row = 0; row  <keyboard.getRowCount(); row++)
		{
			KeyBoxRow kbr = keyboard.keyboardRows.get(row);
			synchronized (kbr.keyboardCols) {
				for (KeyBox keyBox : kbr.keyboardCols)
				{
					for (Character oneChar : keyBox.charList)
					{
						keyboardCharMap.put(oneChar, true);
					}
				}
			}
		}
		
		return keyboardCharMap;
	}
	
	private  HashMap<Character, Boolean> getKeyboardSymbolMap(SoftKeyboard keyboard) {
		HashMap<Character, Boolean> keyboardSymbolMap = new HashMap<Character, Boolean>();
		

		for (Character oneChar : keyboard.leftSymbolKeyBox.charList)
		{
					keyboardSymbolMap.put(oneChar, true);
		}
		
		for (Character oneChar : keyboard.rightSymbolKeyBox.charList)
		{
			keyboardSymbolMap.put(oneChar, true);
		}
		
		return keyboardSymbolMap;
	}
	
	public ArrayList<Character> getFilteredSymbolCharacters(SoftKeyboard keyboard)
	{
		ArrayList<Character> filteredSymbolList = new ArrayList<Character>();
		HashMap<Character, Boolean> keyboardSymbolMap = getKeyboardSymbolMap(keyboard);
		
		for (Character oneChar : keyboardCharConfig.candSymbolList)
		{
			if (!keyboardSymbolMap.containsKey(oneChar))
			{
				filteredSymbolList.add(oneChar);
			}
		}
		
		return filteredSymbolList;
	}
	
	public Character getCharacter(SoftKeyboard keyboard, int row, int col)
	{
		if (candCharacterListMode == CandCharacterListMode.Character)
		{
			return getCharacter(getFilteredCharacters(keyboard), row, col);
		} else if (candCharacterListMode == CandCharacterListMode.Symbol)
		{
			return getCharacter(getFilteredSymbolCharacters(keyboard), row, col);
		}
		
		return null;
	}
	
//	public Character getSymbolCharacter(SoftKeyboard keyboard, int row, int col)
//	{
//		return getCharacter(getFilteredSymbolCharacters(keyboard), row, col);
//	}
	
	public Character getCharacter(ArrayList<Character> characterList, int row, int col)
	{
		Character oneChar = null;
		int pageCharCount = candKeyboardRowCnt * candScreenColCnt;
		int index = col / candScreenColCnt * pageCharCount + row * candScreenColCnt +col % candScreenColCnt;
		
		if (index >=0 && index < characterList.size())
		{
			oneChar = characterList.get(index);
		}
		
		return oneChar;
	}
	
	public boolean resizeCandLayout(CandidateKeyboardLocation ckl, CandCharacterListMode candCharacterListMode)
	{
		int width = GlobalVar.ScreenWidth;
		int height = GlobalVar.candKeyboardBottomY - GlobalVar.candKeyboardTopY;
		this.candCharacterListMode = candCharacterListMode;
		calcCandKeyboardLayout(width, height, candCharacterListMode);
		ckl.refreshLocation();
		
		return true;
	}
}
